home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / bricon / source / inp.c < prev    next >
Text File  |  1991-10-18  |  10KB  |  440 lines

  1. #include    <jctype.h>
  2.  
  3. #define    TRUE    1
  4. #define    FALSE    0
  5. #define    ERR    (-1)
  6.  
  7. #define BUF_MAX 512
  8. #define BUF_MSK 511
  9. #define LIN_MAX 128
  10.  
  11. char    *file_ext();
  12.  
  13. extern    int    fext_top;
  14. extern    int    fext_pos;
  15.  
  16. static  int     his_pos=0;
  17. static  int     his_top=0;
  18. static  int     his_old=0;
  19. static  int     his_blk=0;
  20. static  char    *his_lin;
  21. static  char    his_buf[BUF_MAX];
  22. static  int     his_len[2]={0,0};
  23. static  char    his_tmp[2][LIN_MAX];
  24.  
  25. /************************
  26. int    iskanji(ch)
  27. unsigned char ch;
  28. {
  29.     return ( (ch >= 0x81 && ch <= 0x9F) ||
  30.          (ch >= 0xE0 && ch <= 0xFC) ? TRUE:FALSE);
  31. }
  32. int    iskanji2(ch)
  33. unsigned char ch;
  34. {
  35.     return ( (ch >= 0x40 && ch <= 0x7E) ||
  36.          (ch >= 0x80 && ch <= 0xFC) ? TRUE:FALSE);
  37. }
  38. **************************/
  39. int     iskan(p)
  40. char    *p;
  41. {
  42.     if ( iskanji(*p) && iskanji2(*(p+1)) )
  43.         return TRUE;
  44.     else
  45.         return FALSE;
  46. }
  47. int     kan_pos(p,len)
  48. register char *p;
  49. int     len;
  50. {
  51.     int     i,n;
  52.  
  53.     for ( i = 0 ; *p != '\0' && i < len ; ) {
  54.         n = (iskan(p) ? 2:1);
  55.         if ( (i + n) > len )
  56.             break;
  57.         i += n;
  58.         p += n;
  59.     }
  60.     return i;
  61. }
  62. static  void    his_set(str,len)
  63. char    *str;
  64. int     len;
  65. {
  66.     int     c;
  67.  
  68.     while ( len-- > 0 && *str != '\0' ) {
  69.         his_buf[his_pos++] = *(str++);
  70.         his_pos &= BUF_MSK;
  71.         if ( his_pos == his_top ) {
  72.             do {
  73.                 c = his_buf[his_top++];
  74.                 his_top &= BUF_MSK;
  75.             } while ( his_top != his_pos && c != '\n' );
  76.         }
  77.     }
  78. }
  79. static  int     his_next(pos)
  80. int     pos;
  81. {
  82.     int     c;
  83.  
  84.     while ( pos != his_pos ) {
  85.         c = his_buf[pos++];
  86.         pos &= BUF_MSK;
  87.         if ( c == '\n' )
  88.             break;
  89.     }
  90.     return pos;
  91. }
  92. static  int     his_back(pos)
  93. int     pos;
  94. {
  95.     int     c;
  96.  
  97.     if ( pos == his_top )
  98.         return pos;
  99.  
  100.     pos = (pos - 1) & BUF_MSK;
  101.     while ( pos != his_top ) {
  102.         pos = (pos - 1) & BUF_MSK;
  103.         if ( his_buf[pos] == '\n' ) {
  104.             pos = (pos + 1) & BUF_MSK;
  105.             break;
  106.         }
  107.     }
  108.     return pos;
  109. }
  110. static  int     his_get(str,pos,off,max)
  111. char    *str;
  112. int     pos;
  113. int     off;
  114. int     max;
  115. {
  116.     int     i,n;
  117.  
  118.     i = 0;
  119.     while ( i < max && pos != his_pos ) {
  120.         if ( his_buf[pos] == '\n' )
  121.             break;
  122.         else if ( iskanji(his_buf[pos]) &&
  123.                   iskanji2(his_buf[(pos+1)&BUF_MSK]) )
  124.             n = 2;
  125.         else
  126.             n = 1;
  127.  
  128.         if ( (i + n) > max )
  129.             break;
  130.  
  131.         if ( i >= off ) {
  132.             i += n;
  133.             while ( n-- > 0 ) {
  134.                 *(str++) = his_buf[pos++];
  135.                 pos &= BUF_MSK;
  136.             }
  137.         } else {
  138.             pos = (pos + n) & BUF_MSK;
  139.             while ( n-- > 0 ) {
  140.                 if ( ++i > off )
  141.                     *(str++) = ' ';
  142.                 else
  143.                     str++;
  144.             }
  145.         }
  146.     }
  147.     return (i > off ? i:off);
  148. }
  149. static  int     his_cmp(pos,str,len)
  150. int     pos;
  151. char    *str;
  152. int     len;
  153. {
  154.     while ( len > 0 && *str != '\0' ) {
  155.         if ( pos == his_pos || his_buf[pos++] != *(str++) )
  156.             return FALSE;
  157.         pos &= BUF_MSK;
  158.         len--;
  159.     }
  160.     return TRUE;
  161. }
  162. char    *input(max)
  163. int    max;
  164. {
  165.     int     ch,och,n,i;
  166.     int     pos,cps,len,his;
  167.     char    *p,*s;
  168.  
  169.     ch = pos = cps = len = 0;
  170.     his = his_pos;
  171.     his_lin = his_tmp[his_blk];
  172.  
  173.     if ( max > LIN_MAX )
  174.     max = LIN_MAX;
  175.  
  176.     if ( --max < 0 ) {
  177.     his_lin[0] = '\n';
  178.     len = 1;
  179.     goto ENDOF;
  180.     }
  181.  
  182.     for ( ; ; ) {
  183.  
  184.     och = ch;
  185.  
  186.         if ( (ch = GETCH()) == 0x1B )
  187.         ch = (ch << 8) | GETCH();
  188.  
  189.         switch(ch) {
  190.         case 0x08:
  191.             if ( pos > 0 ) {
  192.                 pos = kan_pos(his_lin,pos - 1);
  193.                 p = &(his_lin[pos]);
  194.                 n = (iskan(p) ? 2:1);
  195.                 memcpy(p,p + n,len - pos - n);
  196.                 len -= n;
  197.  
  198.                 BAKSPC(n);
  199.                 PUTS(p,len - pos);
  200.                 REPCHR(' ',n);
  201.                 BAKSPC(len - pos + n);
  202.             }
  203.             break;
  204.  
  205.         case 0x1B56:
  206.             if ( pos < len ) {
  207.                 p = &(his_lin[pos]);
  208.                 n = (iskan(p) ? 2:1);
  209.                 memcpy(p,p + n,len - pos - n);
  210.                 len -= n;
  211.  
  212.                 PUTS(p,len - pos);
  213.                 REPCHR(' ',n);
  214.                 BAKSPC(len - pos + n);
  215.             }
  216.             break;
  217.  
  218.         case 0x1C:
  219.             if ( pos < len ) {
  220.                 p = &(his_lin[pos]);
  221.                 n = (iskan(p) ? 2:1);
  222.                 pos += n;
  223.  
  224.                 while ( n-- > 0 )
  225.                     PUTC(*(p++));
  226.             }
  227.             break;
  228.  
  229.         case 0x1D:
  230.             if ( pos > 0 ) {
  231.                 pos = kan_pos(his_lin,pos - 1);
  232.                 p = &(his_lin[pos]);
  233.                 n = (iskan(p) ? 2:1);
  234.  
  235.                 BAKSPC(n);
  236.             }
  237.             break;
  238.  
  239.     case 0x1E:
  240.         for ( ; ; ) {
  241.             if ( his == his_top ) {
  242.             BEEP();
  243.             break;
  244.         }
  245.  
  246.                 his = his_back(his);
  247.         cps = ((och == 0x1F || och == 0x1E) ? cps:pos);
  248.                 if ( !his_cmp(his,his_lin,cps) )
  249.                     continue;
  250.  
  251.                 BAKSPC(pos);
  252.                 REPCHR(' ',len);
  253.                 BAKSPC(len);
  254.  
  255.                 pos = len = his_get(his_lin,his,0,max);
  256.  
  257.                 PUTS(his_lin,len);
  258.                 BAKSPC(len - pos);
  259.                 break;
  260.             }
  261.             break;
  262.  
  263.         case 0x1F:
  264.             for ( ; ; ) {
  265.         if ( his == his_pos ) {
  266.             BEEP();
  267.             REPCHR(' ',len - pos);
  268.             BAKSPC(len - pos);
  269.             len = pos;
  270.             break;
  271.         }
  272.  
  273.                 his = his_next(his);
  274.         cps = ((och == 0x1F || och == 0x1E) ? cps:pos);
  275.                 if ( !his_cmp(his,his_lin,cps) )
  276.                     continue;
  277.  
  278.                 BAKSPC(pos);
  279.                 REPCHR(' ',len);
  280.                 BAKSPC(len);
  281.  
  282.                 pos = len = his_get(his_lin,his,0,max);
  283.  
  284.                 PUTS(his_lin,len);
  285.                 BAKSPC(len - pos);
  286.                 break;
  287.             }
  288.             break;
  289.  
  290.     case 0x16:
  291.         case 'R'-'@':
  292.             if ( his != his_top ) {
  293.                 his = his_back(his);
  294.  
  295.                 REPCHR(' ',len - pos);
  296.                 BAKSPC(len - pos);
  297.  
  298.                 len = his_get(his_lin,his,pos,max);
  299.  
  300.                 PUTS(&(his_lin[pos]),len - pos);
  301.                 BAKSPC(len - pos);
  302.             } else
  303.         BEEP();
  304.             break;
  305.  
  306.     case 0x17:
  307.         case 'E'-'@':
  308.             if ( his != his_pos ) {
  309.                 his = his_next(his);
  310.  
  311.                 REPCHR(' ',len - pos);
  312.                 BAKSPC(len - pos);
  313.  
  314.                 len = his_get(his_lin,his,pos,max);
  315.  
  316.                 PUTS(&(his_lin[pos]),len - pos);
  317.                 BAKSPC(len - pos);
  318.             } else
  319.         BEEP();
  320.             break;
  321.  
  322.     case 0x1B55:
  323.         case 'A'-'@':
  324.             p = &(his_lin[len]);
  325.             while ( len < max && *p != '\n' && *p != '\0' ) {
  326.                 len++;
  327.                 p++;
  328.             }
  329.             PUTS(&(his_lin[pos]),len - pos);
  330.             pos = len;
  331.             break;
  332.  
  333.         case 0x0D:
  334.             his_lin[len++] = '\n';
  335.             if ( len > 1 && !his_cmp(his_old,his_lin,len) ) {
  336.         his_old = his_pos;
  337.                 his_set(his_lin,len);
  338.         }
  339.  
  340.             PUTS(&(his_lin[pos]),len - pos);
  341.             goto ENDOF;
  342.  
  343.         case 'X'-'@':
  344.             BAKSPC(pos);
  345.             REPCHR(' ',len);
  346.             BAKSPC(len);
  347.             pos = len = 0;
  348.             break;
  349.  
  350.     case 0x0B:
  351.         case 'D'-'@':
  352.             BAKSPC(pos);
  353.             REPCHR(' ',len);
  354.             BAKSPC(len);
  355.  
  356.             his_len[his_blk] = len;
  357.             his_blk ^= 1;
  358.             his_lin = his_tmp[his_blk];
  359.             pos = len = his_len[his_blk];
  360.  
  361.             PUTS(his_lin,len);
  362.             break;
  363.  
  364.         case 'U'-'@':
  365.         if ( och != ('U'-'@') )
  366.         file_end();
  367.  
  368.         s = file_ext(his_lin,pos);
  369.  
  370.         if ( (n = fext_pos + strlen(s) - pos) > 0 ) {
  371.         if ( pos < len ) {
  372.                     p = &(his_lin[len + (n - 1)]);
  373.                     for ( i = len - pos ; i > 0 ; i--,p-- )
  374.                         *p = *(p - n);
  375.                 }
  376.         } else if ( n < 0 ) {
  377.         if ( pos < len )
  378.             memcpy(&(his_lin[pos+n]),&(his_lin[pos]),len-pos);
  379.         }
  380.  
  381.         p = &(his_lin[fext_pos]);
  382.         while ( *s != '\0' )
  383.         *(p++) = *(s++);
  384.  
  385.             BAKSPC(pos - fext_pos);
  386.             REPCHR(' ',len - fext_pos);
  387.             BAKSPC(len - fext_pos);
  388.  
  389.         len += n;
  390.         pos += n;
  391.  
  392.             PUTS(&(his_lin[fext_pos]),len - fext_pos);
  393.             BAKSPC(len - pos);
  394.         break;
  395.  
  396.         default:
  397.             if ( iskanji(ch) ) {
  398.                 n = GETCH();
  399.                 if ( !iskanji2(n) ) {
  400.                     UNGETCH(n);
  401.                     n = 1;
  402.                 } else {
  403.                     ch = (ch << 8) | n;
  404.                     n = 2;
  405.                 }
  406.             } else
  407.                 n = 1;
  408.  
  409.             if ( (len + n ) >= max ) {
  410.                 BEEP();
  411.                 break;
  412.             }
  413.  
  414.             if ( pos < len ) {
  415.                 p = &(his_lin[len + (n - 1)]);
  416.                 for ( i = len - pos ; i > 0 ; i--,p-- )
  417.                     *p = *(p - n);
  418.             }
  419.  
  420.             p = &(his_lin[pos]);
  421.             if ( n == 1 ) {
  422.                 his_lin[pos++] = ch;
  423.             } else {
  424.                 his_lin[pos++] = ch >> 8;
  425.                 his_lin[pos++] = ch;
  426.             }
  427.             len += n;
  428.  
  429.             PUTS(p,len - pos + n);
  430.             BAKSPC(len - pos);
  431.             break;
  432.         }
  433.         FLUSH();
  434.     }
  435.  
  436. ENDOF:
  437.     his_len[his_blk] = len;
  438.     return his_lin;
  439. }
  440.